import useGetComponentInfo from '@/hooks/useGetComponentInfo'
import { memo, useState, useRef, useEffect } from 'react'
import styles from './index.module.scss'
import { EyeInvisibleOutlined, LockOutlined } from '@ant-design/icons'
import { message, Space, Button, Input, InputRef } from 'antd'
import {
  changeSelectedId,
  ComponentInfoType,
  changeComponentVisible,
  toggleComponentLock,
  changeComponentTitle,
  moveComponent,
} from '@/store/modules/componentsReducer'
import { useDispatch } from 'react-redux'
import classNames from 'classnames'
import SortableContainer from '@/components/DragSortable/SortableContainer'
import SortableItem from '@/components/DragSortable/SortableItem'

const Layer = memo(() => {
  const { componentList, selectedId } = useGetComponentInfo()
  const dispatch = useDispatch()

  const [changingTitleId, setChangingTitleId] = useState('')

  const changeHidden = (fe_id: string, isHidden: boolean) => {
    dispatch(changeComponentVisible({ id: fe_id, isHidden }))
  }

  const changeLocked = (fe_id: string) => {
    dispatch(toggleComponentLock({ id: fe_id }))
  }

  const inputRef = useRef<InputRef>(null)

  const handleTitleClick = (fe_id: string) => {
    const curComp = componentList.find((c: ComponentInfoType) => c.fe_id === fe_id)
    if (curComp && curComp.isHidden) {
      message.warning('不能选中隐藏的组件')
      return
    }
    if (fe_id !== selectedId) {
      dispatch(changeSelectedId(fe_id))
      return
    }
    setChangingTitleId(fe_id)
  }

  // 输入框自动聚焦
  useEffect(() => {
    if (changingTitleId) {
      inputRef.current?.focus()
    }
  }, [changingTitleId])

  const changeTitle = (e: any) => {
    const newTitle = e.target.value.trim()
    if (!newTitle) return
    dispatch(changeComponentTitle({ id: changingTitleId, title: newTitle }))
  }

  const componentListWithId = componentList.map((item: ComponentInfoType) => {
    return {
      id: item.fe_id,
      ...item,
    }
  })

  const handleDragEnd = (oldIndex: number, newIndex: number) => {
    dispatch(moveComponent({ oldIndex, newIndex }))
  }

  return (
    <SortableContainer items={componentListWithId} onDragEnd={handleDragEnd}>
      {componentList.map((item: ComponentInfoType) => {
        const { fe_id, title, isHidden, isLocked } = item

        const titleDefaultClassName = styles.title
        const selectedClassName = styles.selected
        const titleClassName = classNames({
          [titleDefaultClassName]: true,
          [selectedClassName]: fe_id === selectedId,
        })

        return (
          <SortableItem key={fe_id} id={fe_id}>
            <div className={styles.wrapper}>
              <div className={titleClassName} onClick={() => handleTitleClick(fe_id)}>
                {(fe_id === changingTitleId && (
                  <Input
                    ref={inputRef}
                    value={title}
                    onChange={changeTitle}
                    onPressEnter={() => setChangingTitleId('')}
                    onBlur={() => setChangingTitleId('')}
                  />
                )) ||
                  title}
              </div>
              <div className={styles.handler}>
                <Space>
                  <Button
                    size="small"
                    shape="circle"
                    className={!isHidden ? styles.btn : ''}
                    icon={<EyeInvisibleOutlined />}
                    type={isHidden ? 'primary' : 'text'}
                    onClick={() => changeHidden(fe_id, !isHidden)}
                  />
                  <Button
                    size="small"
                    shape="circle"
                    className={!isLocked ? styles.btn : ''}
                    icon={<LockOutlined />}
                    type={isLocked ? 'primary' : 'text'}
                    onClick={() => changeLocked(fe_id)}
                  />
                </Space>
              </div>
            </div>
          </SortableItem>
        )
      })}
    </SortableContainer>
  )
})

export default Layer
